package com.C1对象及变量的并发访问.S1synchronized同步方法.S3synchronized方法与对象锁;

/**
 * @Auther: SJZ    2907374717@qq.com
 * @Date: 2019/3/13 23:01
 * @Description:synchronized 与对象锁
 *
 * 为了证明之前所讲的线程锁是对象
 *
 * 调用关键字synchronized 的声明的方法一定是排队运行的，另外需要记住“共享”这两个字，只有
 * 共享资源的读写访问才需要格式同步化，如果不是共享资源，那么根本没有同步的必要。
 *
 *
 * A线程先保持object对象的Lock锁，B线程可以以异步的方式调用object对象中异步方法
 * A线程先持有object对象的Lock锁，B线程如果这时调用object对象中synchronized类型的方法则需要等待
 * 也就是同步。
 */
public class Test {

    synchronized     void methodA(){
        System.out.println("begin methodA threadName="+Thread.currentThread().getName());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //同步需要等待，所以最后打印
        System.out.println("a end time="+System.currentTimeMillis());
    }

    void methodB(){
        System.out.println("begin methodB threadName="+Thread.currentThread().getName());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("b end");
    }

    public static void main(String[] args) {
        Test test= new Test();
        ThreadA a= new ThreadA(test);
        a.setName("a");
        ThreadB b=new ThreadB(test);
        b.setName("b");
        a.start();
        b.start();
    }

    static class ThreadA extends Thread{
        private Test test;
        public ThreadA(Test test){
            super();
            this.test=test;
        }
        public void run(){
            super.run();
            test.methodA();
        }
    }

    static class ThreadB extends Thread{
        private Test test;
        public ThreadB(Test test){
            super();
            this.test=test;
        }
        public void run(){
            super.run();
            test.methodB();
        }
    }
}
